Microsoft CodeView & Utilities
==============================
CHAPTER 6 ___ EXAMINING DATA AND EXPRESSIONS
(First half)

The CodeView debugger provides several commands for examining different kinds
of data, including expressions, symbols, memory, and registers.  The data-
evaluation commands discussed in this chapter are discussed below.

Command			Action
-------------------------------
Display Expression (?)	Evaluates and displays the value of symbols or
			expressions

Examine Symbol (X?)	Displays the addresses of symbols

Dump (D)		Displays sections of memory containing data (with
			variations for examining different kinds of data)

Compare Memory (C)	Compares two blocks of memory, byte by byte

Search Memory (S)	Scans memory for specified byte values

Port Input (I)		Reads a byte from a hardware port

Register (R)		Shows the current values of each register & each flag

8087 (7)		Shows the current value in the 8087 or 80287 register


6.1  Display Expression Command

The Display Expression command displays the value of a CodeView expression.

Each of the expression evaluators (C, FORTRAN, BASIC, and Pascal) accepts a
different set of symbols, operators, functions, and constants, as explained in
Chapter 4, "CodeView Expressions."  The resulting expressions can contain the
intrinsic functions listed for the FORTRAN and BASIC expression evaluators.
They may also contain functions that are part of the executable file.  The
simplest form of expression is a symbol representing a single variable or
routine.
----
Note
----
FORTRAN subroutines and BASIC subprograms do not return values as func-
tions do.  They can be used in expressions, and in fact may be useful for
observing side effects.  However, the value returned by the expression 
will be meaningless.
====

In addition to displaying values, the Display Expression command can also set
values as a side effect.  For example, with the C expression evaluator you can
increment the variable n by using the expression ++n with the Display Expres-
sion command.  With the FORTRAN expression evaluator you would use LET N=N+1.
After being incremented, the new value will be displayed.

You can specify the format in which the values of expressions are displayed by
the Display Expression command.  Type a comma after the expression, followed
by a CodeView format specifier.  The format specifiers used in the CodeView
debugger are a subset of those used by the C printf function.  They are listed
in Table 6.1.

Table 6.1  CodeView Format Specifiers
-----------------------------------------------------------------------
		Output				Sample		Sample
Character	Format				Expression	Output
-----------------------------------------------------------------------
d		Signed decimal integer		?400000,d	400000
i		Signed decimal integer		?400000,i	400000
u		Unsigned decimal integer	?400000,u	400000
o		Unsigned octal integer		?400000,o	400000
x or X		Hexadecimal integer		?400000,x	9c40
f		Signed value in floating-	?3./2.,f	1.500000
		point decimal format with
		six decimal places 
e or E		Signed value in scientific	?3./2.,e	1.500000e+000
		notation format with up to
		six decimal places (trailing
		zeros and decimal point are
		truncated)
g or G		Signed value with floating-	?3./2.,g	1.5
		point decimal format (f) or
		scientific notation format
		(g or G), whichever is more
		compact
c		Single character		?65,c		A
s		Characters printed up to	?"String",s	String
		the first null character

u - FORTRAN and BASIC have no unsigned data types.  Using an unsigned format
specifier has no effect on the output of positive numbers, but causes negative
numbers to be output as positive values.
x or X - Hexadecimal letters are uppercase if the type is X and lowercase if
the type is x.
e or E, g or G - The "E" is uppercase if the type is E or G; lowercase if the
type is e or g.
s - The s string format is used only with the C expression evaluator; it
prints characters up to the first null.

If no format specifier is given, single- and double-precision real numbers are
displayed as if the format specifier had been given as g. (If you are familiar
with the C language, you should note that the n and p format specifiers and
the F and H prefixes are not supported by the CodeView debugger, even though
they are supported by the C printf function.)

The prefix h can be used with the integer format specifiers (d, o, u, x, and
X) to specify a two-byte integer.  The prefix 1 can be used with the same
types to specify a four-byte integer.  For example, the command ?100000,1d
produces the output 100000.  However, the command ?100000,hd evaluates only
the low-order two bytes, producing the output -31072.
The Display Expression command does not work for programs assembled with
Microsoft Macro Assembler Versions 4.0 and earlier, because the assembler does
not write information to the object file about the type size of each variable.
Use the Dump command instead.

When calling a FORTRAN subroutine that uses alternate returns, the value of
the return labels in the actual parameter list must be 0.  For example, the
subroutine call CALL PROCESS (I,*10,J,*20,*30) must be called from the
debugger as ?PROCESS(IARG1,0,IARG2,0,0).  Using other values as return labels
will cause the error   Type clash in function argument or Unknown symbol.
----
Note
----
Do NOT use a type specifier when evaluating strings in FORTRAN, BASIC, or
Pascal. Simply leave off the type specifier, and the expression evaluator
will display the string correctly. The s type specifier assumes the C 
language string format, with which other languages conflict; if you use
 s, then the debugger will simply display characters at the given address
until a null is encountered.
====

<*> Mouse

The Display Expression command cannot be executed with the mouse.

<*> Keyboard

The Display Expression command cannot be executed with a keyboard command.

<*> Dialog

To display the value of an expression using a dialog command, enter a command
line with the following syntax:

? expression[,format]

The expression is any valid CodeView expression, and the optional format is a
CodeView format specifier.

The remainder of this section first gives examples that are relevant to all
languages, and then gives examples specific to C, FORTRAN, BASIC, and Pascal.

If you are debugging code written with the assembler, you will use the C
expression evaluator by default.  Consult Section 4.5 for guidelines on how to
use the C expression evaluator with assembly code.

<*> Examples

>? amount
500
>? amount,x
1f4
>? amount,o
764
>
The example above displays the value stored in the variable   amount, an
integer.  This value is first displayed in the system radix (in this case,
decimal), then in hexadecimal, and then in octal.

>? 92,x
5c
>? 109*(35+2),o
7701
>? 118,c
v
>

The example above shows how the CodeView debugger can be used as a calculator.
You can convert between radixes, calculate the value of constant expressions,
or check ASCII equivalences.

>? chance,f
0.083333
>? chance,e
8.333333e-002
>? chance,E
8.333333E-002

The example above shows a double-precision real number, chance, displayed in
three formats.  The f format always displays six digits of precision.  The e
format uses scientific notation.  Note that the E format yields essentially
the same display as e does.  The rest of the examples in this section are
specific to particular languages.

<*> C Examples

The following examples assume that a C source file is being debugged, and that
it contains the following declarations:

char *text = "Here is a string."
int  amount;
struct {
		char		name[20];
		int		id;
		long		class;
} student, *pstudent;

int square(int);

Assume also that the program has been executed to the point where the above var-
iables have been assigned values, and that the C expression evaluator is in use.

>? text, X
13F3
>DA Ox13F3
3D83:13F0  Here is a string.
>? text,s
Here is a string.
>
The example above shows how to examine strings.  One method is to evaluate the
variable that points to the string, and then dump the values at that address
(the Dump commands are explained in Section 6.3).  A more direct method is to
use the s type specifier.

>? student.id
19643
>? pstudent->id
19643
>

The example above illustrates how to display the values of members of a
structore.  The same syntax applies to unions.

>? amount
500
>? ++amount
501
>? amount=600
600
>

The example above shows how the Display Expression command can be used with
the C expression evaluator to change the values of variables.

>? square(9)
81
>

The example above shows how functions can be evaluated in expressions.  The
CodeView debugger executes the function   square  with an argument of 9, and
displays the value returned by the function.  You can only display function
values after you have executed into the function   main.

<*> FORTRAN Examples

The examples below assume that the FORTRAN source file contains the following
variable declarations, in which SQUARE is a function:

INTEGER*2 SQUARE
INTEGER*2 AMOUNT
CHARACTER*16 STR
STR = 'Here is a string'

Assume also that the program has executed to the point where these variables
have been assigned values, and that the FORTRAN expression evaluator has been
selected.

>? STR
'Here is a string'

The example above shows how to examine strings with the FORTRAN expression
evaluator.  The s format specifier is not required.

>? AMOUNT
500
>? AMOUNT=AMOUNT+1
501
>? AMOUNT=600
600
>? AMOUNT
600
>

The example above shows how functions can be evaluated in expressions.  The
CodeView debugger executes the function SQUARE with an argument of 9, and
displays the value returned by the function.  You can only display the values
of functions after you have executed into the main program level.

<*> BASIC Examples

These examples assume that the BASIC source file contains the following
statements:

amount% = 500
str$ = "Here is a string"

Assume also that the program has been executed up to these statements, and
that the BASIC expression evaluator is in use.

>? str$
Here is a string

The first example above shows how to examine strings with BASIC expression
evaluator.  The s format specifier should not be used.

>? ASC(str$)
72

The second example demonstrates one of the BASIC intrinsic functions
supported by the CodeView debugger, ASC, which returns the ASCII value of the
first character in a string.

>? amount%
500
>? LET amount%=amount%+1
501
>? LET amount%=600
600
>? amount%
600
>

The example above shows how the Display Expression command can be used to
change values with the BASIC expression evaluator.  With BASIC, the LET
command cna only be applied to a numeric data, not strings.
----
Note
----
The BASIC expression evaluator cannot evaluate functions defined in the
program, as the C and FORTRAN expression evaluators can.
====

<*> Pascal Examples

The following examples assume that a Pascal source file has the following
declarations:

type student = record
			name = string(20);
			id : integer;
			class : integer4;
			end;
	mycard = (jack, queen, king, ace);

var	amount : integer;
	str : string(16);
	tom : student;
	mycard : card;

function square (n: integer) : integer;
begin
	square := n * n;
end

Assume also that the program has been executed to the point where all these
variables have been assigned values, and that the Pascal expression evaluator
is in use.

>? str
This is a string
>? tom.id
19643
>? ORD(mycard)
2
>? ORD(SUCC(mycard))
3

The example above shows how various Pascal types can be evaluated.  Note that
the s type specifier must NOT be used to evaluate strings.

>? amount
500
>? amount := amount+1
501
>? amount := 600
600
>? amount
600
>

The example above demonstrates how the assignment operator can be used to
change values.

>? mycard = king
2
>

The example above shows how to assign values to enumerated types.  In this
case   king  is not a variable, but an enumerated-type constant value.

>? square(3)+1
10
>

The example above shows how a function defined in the source code can be used
in a CodeView expression.

<*> Assembly Examples

By default, the C expression evaluator is used for debugging assembly modules.
However, some C expressions are particularly helpful for debugging assembly
code.  Some typical examples are presented below.

>? BY bx
12
>

The example above displays the first byte at the location pointed to by BX,
and is equivalent to the assembly expression BYTE PTR [bx].

>? WO bp+8
9359
>

The example above displays the first word at the location pointed to by [bp+8].

>? DW si+12
12555324
>

The example above displays the first double word at the location pointed to
by [si+12].

>? (char) var
5
>? (int) var
1005
>

The last two examples use type casts, which are similar to the assembler PTR
operator.  The expression (char) var displays the byte at the address of  var,
in signed format.  The expression (int) var displays the word at the same
address, also in signed format.  You can alter either of these commands to
display results in unsigned format simply by using the U format specifier.
>? (char) var,u

>? (int) var,u

6.2  Examine Symbols Command

The Examine Symbols command displays the names and addresses of symbols, and
the names of modules, defined within a program.  You can specify the symbol or
group of symbols you want to examine by module, procedure, or symbol name.

<*> Mouse

The Examine Symbols command cannot be executed with the mouse.

<*> Keyboard

The Examine Symbols command cannot be executed with a keyboard command.

<*> Dialog

To view the addresses of symbols with a dialog command, enter a command line
in one of the following formats:

X*
X
X? [module!][routine.][symbol][*]

in which   routine  is in a program unit, such as a C function or a BASIC
subprogram, capable of having its own local variables. The syntax combinations
are listed in more detail below.

Syntax				Display
-------------------------------------
X?module!routine.symbol		The specified symbol is the specified routine
				in the specified module.

X?module!routine.*		All symbols in the specified routine in
				the specified   module.

X?module!symbol			The specified symbol in the specified module
				(symbols within routines are not found).

X?module!*			All symbols in the specified   module.

X?routine.symbol		The specified symbol in the specified routine
				(looks for routine first in the current module
				and then in other modules from first to last).

X?routine.*			All symbols in the specified routine (looks
				for routine first in the current module and
				then in other modules from first to last).

X?symbol			Looks for the specified symbol in this order:
				1. In the current routine
				2. In the current module
				3. In other modules, from first to last

X?*				All symbols in the current routine.

X*				All module names.

X				All symbolic names in the program, including
				all modules and all symbols.
----
Note
----
When you debug an assembly module, you cannot use the   routine  field,
you MUST use the   module field.  Therefore, the only versions of this
command that work with assembly modules are the following:

X?module!*
X?module!symbol
====

<*> C Examples

For the following examples, assume that the program being examined is called
pi.exe, ant that it consists of two modules:  pi.c and math.c.  The pi.c
module is a skeleton consisting only of the main function, whereas the math.c
module has several functions.  Assume that the current function is div within
the math module.

>X*            ;*Example 1
PI.OBJ
MATH.OBJ
C:B(chkstk)
C:B(crt0)
.
.
.
C:B(itoa)
C:B(unlink)
>

Example 1 lists the two user-created modules of the program, as well as the
library modules used in the program, as well as the library modules used in
the program.

>X?*			;*Example 2
		DI			int			b
		[BP-0006]		int			quotient
		SI			int			i
		[BP-0002]		int			remainder
		[BP+0004]		int			divisor
>

Example 2 lists the symbols in the current function (div).  Local variables
are shown as being stored either in a register (b in register DI) or at a
memory location specified as an offset from a register (divisor at location
[BP+0004]).

>?pi!*		;* Example 3
3D37:19B2 int			_scratch0		3D37:0A10 char			_p[]
3D37:2954 int			_scratch1		3D37:194B char			_t[]
3D37:2956 int			_scratch2		3D37:19B0 int			_q
3A79:0010 int			_main()			3A79:0010 int			main()
3D37:19B2 int			scratch0
3D37:0A10 char			p[]
3D37:2954 int			scratch1
3D37:19B4 char			t[]
3D37:2956 int			scratch2
3D37:19B0 int			q
>

Example 3 shows all the symbols in the pi.c module.

>X?math!div.*		;*Example 4
3A79:0264 int			div()
		DI			int			b
		[BP-0006]		int			quotient
		SI			int			i
		[BP-0002]		int			remainder
		[BP+0004]		int			divisor
>

Example 4 shows the symbols in the div function in module math.c.  You
wouldn't need to specify the module if math.c were the current module, but you
would if the current module were pi.c.

Variables local to a function are indented under that function.

>X?math!arctan.s	;* Example 5
3A79:00FA int			arctan()
          [BP+0004] int			s
>

Example 5 shows one specific variable (s) within the arctan function.

<*> FORTRAN Examples

For the following examples, assume that the program being examined is called
FRUST.EXE, and that it consists of four modules:  FRUST.FOR, FRUST1.FOR,
FRUST2.FOR, and FRUST3.FOR.  Assume that the current routine is main within
the FRUST.FOR module.

>X*
FRUST.OBJ
FRUST1.OBJ
FRUST2.OBJ
FRUST3.OBJ
c:\lib\LLIBFORE.LIB(fixups)
c:\lib\LLIBFORE.LIB(crt0)
c:\lib\LLIBFORE.LIB(chkstk)
c:\lib\LLIBFORE.LIB(wr)
.
.
.
c:\lib\LLIBFORE.LIB(txtmode)
c:\lib\LLIBFORE.LIB(_creat)

The example above lists the four modules called by the program.  The library
files called by the program are also listed.
>X?T
		520D:0DE4 REAL*4         T

The example above shows the address of the variable T in the current module.

>X?FRUST3!MULTPI.*
4B28:0005 INTEGER*4		MULTPI()
			[BP+000A]				V
			[BP+0006]				X                
			[BP-0004] INTEGER*4		MULTPI

The example above lists the symbols in the function MULTPI, located in module
FRUST3.  Variables local to the function are indented under the function.  You
wouldn't need to specify the module if FRUST3 were the current module.
>X?FRUST2!SAREA.*
4B28:0005 void			SAREA()
			[BP+0012]				R1
			[BP+000E]				R2
			[BP+000A]				H
			[BP+0006]				T
			520D:0DEC REAL*4		S12
			520D:0DE8 REAL*4		U

The example above shows all the symbols in the routine SAREA in the module
FRUST2.  Because SAREA is a subroutine instead of a function, the word   void
appears where function return-value types are shown.

<*> BASIC Examples

For the following examples, assume that the program being examined is called
PROG.EXE, and that it consists of the following modules:  PROG.BAS and
SORT.BAS.  Assume that the current routine is the main program (which, unlike
subprograms, has no name in a BASIC program), and that the module SORT.BAS
contains two subprograms, SORT and SWITCH.
>X*
PROG.OBJ
SORT.OBJ
BRUN303.LIB(ftmdata)
BRUN303.LIB(crtO)
BRUN303.LIB(crtOdat)
.
.
.
BRUN303.LIB(doexec)
BRUN303.LIB(execmsg)

The example above lists the two modules of the program, including PROG.OBJ,
which is the main module.  The BASIC library files called by the program are
also listed.

>X?*
		5825:17BE integer		A%[array]
		5825:1780 single		HOURS!
		5825:1784 integer		I%

The example above lists the symbols in the current routine, which happens to
be the main program.  Although the main program has no label and therefore
will not show up in a stack trace, it is still an independent routine and has
jits own local variables.  In BASIC, local variables are not put on the stack
unless they are subprogram parameters.
	
>X?*SORT!*
		572F:0033 integer		SORT()
		572F:00E1 integer		SWITCH()

The example above lists the routines in the module SORT.OBJ.  The form of the
Display Symbols command lists routines only, not variables.  Note that SORT()
and SWITCH() are given with the addresses of the two subprograms by that name.

>X?SORT!SWITCH.*
		[BP+0008] integer		B%
		[BP+0006] integer		C%
		5824:1798 integer		TEMP%

The example above shows all the symbols in the routine SWITCH, which is in the
SORT.OBJ module.  Each represents an integer.  However, B% and C% represent
subprogram parameters that were passed on the stack, whereas TEMP% is a true
subprogram variable.  Therefore, TEMP% has an absolute address in memory,
whereas B% and C% are addressed relative to the stack. (BP points to the value
of the stack at the time the routine SWITCH was called.)


.end of first half.